import 'dart:convert';

import 'package:distribution_mall_flutter/constant/constant.dart';
import 'package:distribution_mall_flutter/entity/address/address_query_entity.dart';
import 'package:distribution_mall_flutter/http/modules/address.dart';
import 'package:distribution_mall_flutter/pages/address/address_search/domain/address_search_entity.dart';
import 'package:distribution_mall_flutter/utils/common_third.dart';
import 'package:distribution_mall_flutter/utils/debug.dart';
import 'package:distribution_mall_flutter/utils/log.dart';
import 'package:distribution_mall_flutter/utils/storage.dart';
import 'package:distribution_mall_flutter/widgets/azlistview/src/az_common.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

abstract class HasName {
  String get name;
}

class RegionModal extends HasName {
  @override
  String name = '';
  String code = '';
  String type = '';
}

class CityModel extends ISuspensionBean {
  String name;
  String? tagIndex;
  String? namePinyin;
  String? postcode;
  String? type;
  String? code;
  bool? leafNode;
  String? virtualPostcode;
  String? parentCode;
  bool? isChild;

  CityModel(
      {this.name = '',
      this.tagIndex = '',
      this.namePinyin = '',
      this.postcode,
      this.type,
      this.code,
      this.leafNode,
      this.virtualPostcode,
      this.parentCode,
      this.isChild});

  Map<String, dynamic> toJson() => {
        'name': name,
        'tagIndex': tagIndex,
        'namePinyin': namePinyin,
        'postcode': postcode,
        'type': type,
        'code': code,
        'leafNode': leafNode,
        'virtualPostcode': virtualPostcode,
        'parentCode': parentCode,
        'isChild': isChild,
      };

  static CityModel fromAddressSearchBodyAddress(
      AddressSearchBodyAddress item, String parentCode) {
    String tag = item.name?.substring(0, 1).toUpperCase() ?? '#';
    bool isTag = RegExp('[A-Z]').hasMatch(tag);
    return CityModel()
      ..name = item.name ?? ''
      ..namePinyin = item.name
      ..postcode = item.postcode
      ..type = item.type
      ..code = item.code
      ..tagIndex = isTag ? tag : '#'
      ..leafNode = item.leafNode
      ..virtualPostcode = item.virtualPostcode
      ..parentCode = parentCode;
  }

  @override
  String getSuspensionTag() => tagIndex ?? '';

  @override
  String toString() => json.encode(this);
}

class AddressQueryState {
  List<AddressQueryEntity> queryList;
  Map<String, dynamic> storeQueryMap;
  List<CityModel> azList;
  List<String> indexBarList;
  Map<String, dynamic> storeIndexBarMap;
  List<CityModel> regionList;
  int regionActive = -1;

  AddressQueryState(
      {this.queryList = const [],
      this.storeQueryMap = const {},
      this.azList = const [],
      this.indexBarList = const [],
      this.storeIndexBarMap = const {},
      this.regionList = const [],
      required this.regionActive});

  AddressQueryState.initial()
      : storeQueryMap = const {},
        queryList = const [],
        azList = const [],
        indexBarList = const [],
        storeIndexBarMap = const {},
        regionList = const [];

  AddressQueryState copyWith(
          {Map<String, dynamic>? storeQueryMap,
          List<AddressQueryEntity>? queryList,
          List<CityModel>? azList,
          List<String>? indexBarList,
          Map<String, dynamic>? storeIndexBarMap,
          List<CityModel>? regionList,
          int? regionActive}) =>
      AddressQueryState(
        storeQueryMap: storeQueryMap ?? this.storeQueryMap,
        queryList: queryList ?? this.queryList,
        azList: azList ?? this.azList,
        indexBarList: indexBarList ?? this.indexBarList,
        storeIndexBarMap: storeIndexBarMap ?? this.storeIndexBarMap,
        regionList: regionList ?? this.regionList,
        regionActive: regionActive ?? this.regionActive,
      );
}

///全局实例合适
final addressQueryProvider =
    StateNotifierProvider<AddressQueryViewModel, AddressQueryState>((ref) {
  return AddressQueryViewModel();
});

class AddressQueryViewModel extends StateNotifier<AddressQueryState> {
  AddressQueryViewModel() : super(AddressQueryState.initial());

  void initData() {
    ///清理之前的数据
    state = state.copyWith(regionList: [], regionActive: -1);
    ///热重载下或者首次没加载出来,会导致这里没有数据
    getQueryList(type: AddressType.province, parentCode: NationCode.ph);
  }

  getQueryList(
      {required String type,
      required String parentCode,
      bool showLoading = false}) async {
    if (!EPstorage.isLogin()) return null;
    if (state.storeQueryMap.containsKey(parentCode) &&
        state.storeQueryMap[parentCode] != null) {
      state = state.copyWith(
          azList: state.storeQueryMap[parentCode],
          indexBarList: state.storeIndexBarMap[parentCode]);
      return;
    }
    if (showLoading) EPLoading.showLoadig();
    try {
      List<AddressQueryEntity>? data = await AddressApi.querySubAddresses(
          {'type': type, 'parentCode': parentCode});
      EPLoading.dis();
      if (data == null) return;
      Map<String, dynamic> queryMap = Map.from(state.storeQueryMap);
      state = state.copyWith(queryList: data, storeQueryMap: queryMap);
      formatQueryList(parentCode);
    } catch (e) {
      EPLoading.dis();
    }
  }

  formatQueryList(String code) {
    List<CityModel> cityList = [];
    List<String> indexBarData = [];
    for (AddressQueryEntity item in state.queryList) {
      CityModel cityModal = CityModel();
      cityModal
        ..name = item.name ?? ''
        ..namePinyin = item.name
        ..postcode = item.postcode
        ..type = item.type
        ..code = item.code
        ..leafNode = item.leafNode
        ..virtualPostcode = item.virtualPostcode
        ..parentCode = item.parentCode;
      String tag = item.name?.substring(0, 1).toUpperCase() ?? '#';
      bool isTag = RegExp('[A-Z]').hasMatch(tag);
      cityModal.tagIndex = isTag ? tag : '#';
      if (!indexBarData.contains(tag)) {
        indexBarData.add(tag);
      }
      cityList.add(cityModal);
    }
    SuspensionUtil.sortListBySuspensionTag(cityList);
    SuspensionUtil.setShowSuspensionStatus(cityList);
    indexBarData.sort();
    if (state.storeIndexBarMap[code] == null) {
      Map<String, dynamic> map = Map.from(state.storeIndexBarMap);
      map[code] = indexBarData;
      state = state.copyWith(storeIndexBarMap: map);
    }
    if (state.storeQueryMap[code] == null) {
      Map<String, dynamic> map = Map.from(state.storeQueryMap);
      map[code] = cityList;
      state = state.copyWith(storeQueryMap: map);
    }
    state = state.copyWith(azList: cityList, indexBarList: indexBarData);
  }

  String addressNextType(String str) {
    switch (str) {
      case 'PROVINCE':
        return 'CITY';
      case 'CITY':
        return 'AREA';
      case 'AREA':
        return 'STREET';
    }
    return '';
  }

  ///列表点击
  bool? clickRegionList({required CityModel item}) {
    println('clickRegionList ${item}');
    List<CityModel> list = List.from(state.regionList);
    list.add(item);
    String nextType = addressNextType(item.type ?? '');
    if (item.leafNode != true) {
      getQueryList(type: nextType, parentCode: item.code!, showLoading: true);
    }
    state = state.copyWith(regionList: list, regionActive: list.length - 1);
    // println('设置后 ${state.regionActive}');
    return item.leafNode;
  }

  ///标题点击
  bool? titleClickRegionList({
    required CityModel item,
    required int index,
  }) {
    List<CityModel> list = List.from(state.regionList);
    list.removeRange(index, list.length);

    if (index == 0) {
      getQueryList(type: AddressType.province, parentCode: NationCode.ph);
    } else {
      var currentSelect = state.regionList[index - 1];
      if (currentSelect.leafNode != true) {
        getQueryList(
            type: currentSelect.type!, parentCode: currentSelect.code!);
      }
    }
    state = state.copyWith(regionList: list, regionActive: index - 1);
    return item.leafNode;
  }

  ///搜索设置
  bool setSearchAddress(AddressSearchBody selectItem) {
    println('setSearchAddress ${state.regionActive} ${selectItem}');
    var list = [
      selectItem.firstAddress!,
      if (selectItem.secondAddress != null) selectItem.secondAddress!,
      if (selectItem.thirdAddress != null) selectItem.thirdAddress!,
      if (selectItem.fourthAddress != null) selectItem.fourthAddress!,
    ]
        .map((e) => CityModel.fromAddressSearchBodyAddress(e, NationCode.ph))
        .toList();
    state = state.copyWith(regionList: list, regionActive: list.length - 1);
    var last = list.last;
    if (last.leafNode != true) {
      String nextType = addressNextType(last.type ?? '');
      getQueryList(type: nextType, parentCode: last.code!, showLoading: true);
    }
    return last.leafNode!;
  }
}
